import copy
from ZIndex.tool import Util
import pandas as pd
import BaoSign as sign
import baostock as bs
import ZIndex.stock.index as index

# 登陆接口
lg = bs.login()
# 显示登陆返回信息
print('login respond error_code:'+lg.error_code)
print('login respond  error_msg:'+lg.error_msg)
# security_list = ['sz.300008', 'sz.002623', 'sz.000665', 'sz.002411', 'sz.300222','sz.002432','sz.002031','sz.300456','sz.300933'
#                 ,'sz.002455','sh.600737','sz.300017','sh.600506','sh.601001','sz.300030','sh.603881','sz.000651']
security_list = ['sz.300008', 'sz.002623', 'sz.000665', 'sz.002411', 'sz.300222','sz.002432','sz.300456','sz.300933'
                ,'sz.002455','sh.600737','sz.300017','sh.600506','sh.603766']




# index_list = ['KDJ_S','LWR_S','MACD_S','BRAR_S', 'LB_S','VRSI_S','MA_S','BOLL_S','OBV_S','MFI_S']
index_list = ['KDJ_S','WR_S','MACD_S', 'LB_S', 'BOLL_S','OBV_S','MFI_S']

# 从待选指标中不重复抽样5个指标
# 随机指标个数
select_num = len(index_list)
select_index = Util.listRandomChoice(index_list, select_num)

### 参数设置 ###
# KDJ 统计的天数
KDJ_N, KDJ_M1, KDJ_M2 = 9, 2, 5
WR_N, WR_N1, WR_N2 = 12, 7, 9
MACD_MID, MACD_LONG, MACD_SHORT, MACD_LONG2, MACD_LONG3 = 13, 48, 12, 47, 60
BRAR_N = 26
CYR_N, CYR_M = 13, 5
LB_N = 6
MACD_M1, MACD_M2 = 5, 10
VRSI_M1, VRSI_M2, VRSI_M3 = 6, 12, 24
MA_N = 5
MA_LONG_N = 15
BOLL_N, BOLL_M = 10, 7
Boll_timeperiod, Boll_nbdevup, Boll_nbdevdn = 20, 2, 2
OBV_TimePeriod = 37
VOL_M1, VOL_M2 = 5, 20
MFI_TimePeriod = 9
### 参数设置 end ###

# 指标权重参数，初始时均为1
weightDict = {'KDJ_S':[1], 'WR_S':[1],'MACD_S':[1],'LB_S':[1],'BOLL_S':[1],'OBV_S':[1],'MFI_S':[1]}
# weightDict = {'KDJ_S':[0.121], 'WR_S':[0.111],'MACD_S':[0.145],'LB_S':[0.258],'BOLL_S':[0.127],'OBV_S':[0.111],'MFI_S':[0.127]}
weightDictDF = pd.DataFrame(weightDict)
# print(weightDictDF)


stock = pd.DataFrame()
final_result = pd.DataFrame()
for stock_code in security_list:
    # 获取前200个交易日数据，除去节假日，
    start_check_date = str(Util.getYesterday(int(200)))
    end_check_date = str(Util.getYesterday(1))
    print("数据开始时间为：" + str(start_check_date))
    print("数据结束时间为：" + str(end_check_date))
    print(stock_code)
    # 获取前五日该指标值，从而找到该指标知期趋势
    # TODO 这个地方有个问题，就是如果是节假日，该数据可能获取不准，
    # check_date_before = util.getYesterday(int(i) + 5)
    # 获取前一交易日日线行情数据
    # adjustflag：复权类型，默认不复权：3；1：后复权；2：前复权。已支持分钟线、日线、周线、月线前后复权。
    rs = bs.query_history_k_data_plus(stock_code,
                                      "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,isST",
                                      start_date=start_check_date, end_date=end_check_date,
                                      frequency="d", adjustflag="3")
    #### 打印结果集 ####
    data_list = []
    while (rs.error_code == '0') & rs.next():
        # 获取一条记录，将记录合并在一起
        data_list.append(rs.get_row_data())
    result = pd.DataFrame(data_list, columns=rs.fields)
    if stock.empty:
        stock = result
    else:
        stock = stock.append(result)
#### 登出系统 ####
bs.logout()
# 获取数据后对数据进行处理
# step 1 按时间进行倒序排列
stock = stock.sort_values(by=['date', 'code'], ascending=True)
Util.dataFrameToCsv(stock, "/result/stock_data_bs.csv", True)
# 默认取最近30天的数据
sign_num = -45
# print(stock)
# step 2 计算各指标值
# 循环取每个股票stock中数据，计算各日期下的指标变化
for stock_code in security_list:
    # 获取股票的数据
    result = stock.loc[stock['code'] == stock_code]
    result = result[['code','date', 'open', 'close', 'high', 'low', 'volume', 'amount']]
    result['open'] = result['open'].astype('float')
    result['close'] = result['close'].astype('float')
    result['high'] = result['high'].astype('float')
    result['low'] = result['low'].astype('float')
    result['volume'] = result['volume'].astype('float')
    result['amount'] = result['amount'].astype('float')
    # 用来存储信号结果
    mid_result = result[sign_num:]
    # 获取KDJ指标 返回K D J的值
    K, D, J = index.KDJIndex(result, N=KDJ_N, M1=KDJ_M1, M2=KDJ_M2)
    result['K'] = K
    result['D'] = D
    result['J'] = J

    KDJ_sign = sign.KDJ_sign(result[sign_num:])
    mid_result['KDJ_S'] = KDJ_sign.values()

    # 获取WR指标，
    WR = index.WR(result, WR_N)
    result['WR'] = WR
    WR_sign = sign.WR_Sign(result[sign_num:])
    mid_result['WR_S'] = WR_sign.values()

    # MACD指标
    macd_dif, macd_dea, macd_macd = index.MACD(result, MACD_SHORT, MACD_LONG, MACD_MID)
    result['macd_dif'] = macd_dif
    result['macd_dea'] = macd_dea
    result['macd_macd'] = macd_macd
    MACD_sign = sign.MACD_sign(result)
    mid_result['MACD_S'] = list(MACD_sign.values())[sign_num:]


    # 获取 BRAR-情绪指标，AR, BR VR CY
    BR, AR = index.BRAR(result, BRAR_N)
    result['BR'] = BR
    result['AR'] = AR
    #
    # CR1, MA1, MA2, MA3, MA4 = CR(security_list, check_date=check_date, N=MACD_LONG, M1=MACD_SHORT, M2=MACD_MID,
    #                              M3=MACD_LONG2, M4=MACD_LONG3)
    # result['CR'] = CR1.values()
    # result['MA1'] = MA1.values()
    # result['MA2'] = MA2.values()
    # result['MA3'] = MA3.values()
    # result['MA4'] = MA4.values()
    #
    # VR_values, MAVR = VR(security_list, check_date=check_date, N=MACD_LONG, M=MACD_SHORT)
    # result['VR'] = VR_values.values()
    BRAR_sign = sign.BRAR_Sign(result[sign_num:])
    mid_result['BRAR_S'] = BRAR_sign.values()


    # CYR_values, MACYR = CYR(security_list, check_date=check_date, N=CYR_N, M=CYR_M)
    # result['CYR'] = CYR_values.values()
    # result['MACYR'] = MACYR.values()
    # CYR_Sign = sign.CYR_Sign(result)
    # result['CYR_S'] = CYR_Sign.values()

    # 量比指股市开市后平均每分钟的成交量与过去N个交易日平均每分钟成交量之比、
    # 量比0.5成交量萎缩到极致，变盘随时发生。 量比0.8--1.5成交量处于正常水平。量比1.5--2.5温和放量，将会延续原有趋势。
    # 量比2.5--5明显放量，可以采取相应行动了。量比5--10放巨量表现，趋势已到末期。量比>10极端放量，趋势已经到默契，可以考虑反向操作。
    lb = index.LB(result, LB_N)
    result['LB'] = lb
    LB_Sign = sign.LB_sign(result[sign_num:])
    mid_result['LB_S'] = LB_Sign.values()

    # MA_N日均线
    MA_values = index.MA(result, MA_N)
    result['MA'] = MA_values
    MA_Sign = sign.MA_sign(result[sign_num:])
    mid_result['MA_S'] = MA_Sign.values()


    # 布林通道线BBANDS
    # # MA_Type: 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3 (Default=SMA)
    upperband, middleband, lowerband = index.BBANDS(result, BOLL_M)
    result['upperband'] = upperband
    result['middleband'] = middleband
    result['lowerband'] = lowerband
    BOLL_Sign = sign.BOLL_Sign(result[sign_num:])
    mid_result['BOLL_S'] = BOLL_Sign.values()


    # 3.OBV：能量潮
    OBV_values = index.OBV(result)
    # MA_20 = MA(security_list, check_date=check_date, timeperiod=MA_LONG_N)
    amount_20 = index.Amount(result, OBV_TimePeriod)
    result['OBV'] = OBV_values
    result['MAVOL2'] = amount_20
    OBV_sign = sign.OBV_sign(result)
    mid_result['OBV_S'] = list(OBV_sign.values())[sign_num:]


    # MFI资金流量指标
    MFI_values = index.MFI(result, MFI_TimePeriod)
    result['MFI'] = MFI_values
    MFI_Sign = sign.MFI_sign(result)
    mid_result['MFI_S'] = list(MFI_Sign.values())[sign_num:]


    print("#########")
    print(mid_result)
    # 根据上述指标重新构建sign结果表
    result_select_index = []
    result_select_index = copy.deepcopy(select_index)
    result_select_index.insert(0, 'date')
    result_select_index.insert(1, 'code')
    result_select_index.insert(2, 'close')


    sign_result_df = mid_result.loc[:, result_select_index]
    # 此处计算指标权重和时，需判断是否为各指标赋权重，如没有赋，则直接求和，否则，按权重来计算
    # if KDJ_S_acc == 0:
    #     sign_result_df['sum'] = sign_result_df[select_index].apply(lambda x: x.sum(), axis=1)
    sign_result_df['sum'] = sign_result_df[select_index].apply(lambda x: x.sum(), axis=1)
    tempSum = sign_result_df[select_index].mul(weightDictDF.loc[0], axis=1)
    sign_result_df['weightsum'] = tempSum.apply(lambda x: round(x.sum(), 3), axis=1)



    # 统计每支股票信号个数
    print(sign_result_df)
    # stock = pd.concat([stock, sign_result_df], axis=1)

    result_select_index.append('sum')
    result_select_index.append('weightsum')
    columns = result_select_index

    mid_result['sum'] = round(sign_result_df['sum'], 3)
    mid_result['weightsum'] = round(sign_result_df['weightsum'], 3)


    # print(columns)
    # sign 数据去重，因节假日获取为上一交易日
    # stock = stock.drop_duplicates()

    if final_result.empty:
        final_result = mid_result
    else:
        final_result = final_result.append(mid_result)



# 去掉重复数据
final_result = final_result.drop_duplicates()
# 排序，按时间来排序
final_result = final_result.sort_values(by=['date', 'code'], ascending=False)
Util.dataFrameToCsv(final_result, "/result/BaoSign_all.csv", True)

Util.dataFrameToCsv(final_result, "/result/BaoSign.csv", True, columns=columns)

print(final_result)















